package com.nebulas.nettyhex.server;


import com.alibaba.fastjson2.JSONObject;
import com.nebulas.websocket.handler.MyWebSocketHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class RuoYiNettyChannelInboundHandlerAdapter extends ChannelInboundHandlerAdapter {

    //换成相对线程安全的ConcurrentHashMap
    public static ConcurrentHashMap<Object, Object> channelMap = new ConcurrentHashMap<>();
    //设备号通道
    public static ConcurrentHashMap<String, ChannelHandlerContext> map = new ConcurrentHashMap<>();

    // 设备id和 通道id 的映射
    public static ConcurrentHashMap<String, String> deviceChannelMap = new ConcurrentHashMap<>();

    /**
     * 从客户端收到新的数据时，这个方法会在收到消息时被调用
     *
     * @param ctx
     * @param msg
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception, IOException {
        String channelId = ctx.channel().id().toString();
        //根据通道获取设备号
        String code = (String) channelMap.get(ctx) != null ? channelMap.get(ctx).toString() : "";
        log.info("收到设备：" + code + msg.toString());
        String arr [] = msg.toString().split(",");
        // 帧头
        String frameHeader = arr[0];
        // 设备ID
        String deviceId = arr[1];
        // 保存设备号和通道号的映射
        deviceChannelMap.put(deviceId, channelId);
        // 设备类型
        String deviceType = arr[2];
        // 经度
        String longitude = arr[3];
        // 纬度
        String latitude = arr[4];
        // 值1
        String value1 = arr[5];
        // 值2
        String value2 = arr[6];
        // 值3
        String value3 = arr[7];
        // 值4
        String value4 = arr[8];
        // 设备状态
        String deviceStatus = arr[9];
        // 频段
        String frequency = arr[10];
        // 信号数
        String signal = arr[11];
        // 校验字
        String check = arr[12];
        JSONObject messageInfor = new JSONObject();
        messageInfor.put("frameHeader", frameHeader);
        messageInfor.put("deviceId", deviceId);
        messageInfor.put("deviceType", deviceType);
        messageInfor.put("longitude", longitude);
        messageInfor.put("latitude", latitude);
        messageInfor.put("value1", value1);
        messageInfor.put("value2", value2);
        messageInfor.put("value3", value3);
        messageInfor.put("value4", value4);
        messageInfor.put("deviceStatus", deviceStatus);
        messageInfor.put("frequency", frequency);
        messageInfor.put("signal", signal);
        messageInfor.put("check", check);
        MyWebSocketHandler.sendAllMessage(messageInfor.toJSONString());
        ctx.writeAndFlush("11111111");
    }


    /**
     * 服务端当read超时, 会调用这个方法
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception, IOException {
        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = inSocket.getAddress().getHostAddress();
        if (evt instanceof IdleStateEvent) {  // 2
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {//读超时
                ctx.close();//超时时断开连接
            } else if (event.state() == IdleState.WRITER_IDLE) {//写超时

            } else if (event.state() == IdleState.ALL_IDLE) {//全部超时
            }
        }
        super.userEventTriggered(ctx, evt);
    }

    /**
     * 连接建立时调用
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String deviceId = channel.id().toString();
        map.put(deviceId, ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String deviceId = ctx.channel().id().asLongText();
        map.remove(deviceId);
    }
}
